package cn.huiyunche.driver.service.impl;

import cn.huiyunche.base.service.mappers.DFuelPriceEffectiveMapper;
import cn.huiyunche.base.service.mappers.ext.DFuelPriceEffectiveExtMapper;
import cn.huiyunche.base.service.model.DFuelPriceEffective;
import cn.huiyunche.base.service.model.DFuelPriceEffectiveExample;
import cn.huiyunche.base.service.vo.DFuelPriceEffectiveVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.driver.service.DFuelPriceEffectiveService;
import cn.huiyunche.driver.service.DVehiclePreKilometerFeeEffectiveService;
import cn.huiyunche.driver.service.form.DFuelPriceEffectiveForm;
import cn.huiyunche.driver.service.query.DFuelPriceEffectiveQueryConditions;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @FileName: cn.huiyunche.driver.service
 * @Description: Description
 * @author: Aaron
 * @date: 2017/2/26 下午6:49
 */
@Service
public class DFuelPriceEffectiveServiceImpl implements DFuelPriceEffectiveService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DFuelPriceEffectiveServiceImpl.class);

    @Autowired
    private DFuelPriceEffectiveMapper dFuelPriceEffectiveMapper;

    @Autowired
    private DVehiclePreKilometerFeeEffectiveService dVehiclePreKilometerFeeEffectiveService;

    @Autowired
    private DFuelPriceEffectiveExtMapper dFuelPriceEffectiveExtMapper;

    @Override
    public Integer add(DFuelPriceEffectiveForm form, BindingResult br) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.add params : {}", form);

        if (null == form) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.add param form must not be null");
            throw new IllegalArgumentException("燃油价格变动表单不能为空");
        }

        //验证表单
        verificationForm(br);

        //验证业务
        verificationBusiness(form);

        /**
         * 查询当前生效的记录，更新失效时间未添加记录的生效时间
         */
        DFuelPriceEffective currentPrice = this.selectByEffectiveDateAndFuelTypeId(form.getFuelTypeId(), new Date());
        if (null != currentPrice) {
            currentPrice.setInvalidDate(form.getEffectiveDate());
            this.update(currentPrice);
        }

        /**
         * 生成车型每公里油费变动
         */
//        dVehiclePreKilometerFeeEffectiveService.automaticGeneration(effective.getFuelTypeId(), effective.getId(), effective.getMarketPrice(), effective.getEffectiveDate());

        DFuelPriceEffective effective = new DFuelPriceEffective();
        BeanUtils.copyProperties(form, effective);

        return dFuelPriceEffectiveMapper.insertSelective(effective);
    }

    private void verificationBusiness(DFuelPriceEffectiveForm form) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.verificationBusiness param : {}", form);


        List<DFuelPriceEffective> list = this.selectByFuelTypeId(form.getFuelTypeId());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }

        /**
         * 是否已经存在未激活的里程变动
         * 激活时间大于
         */
        List<DFuelPriceEffective> collect = list.stream().filter(
                o -> -1 != o.getEffectiveDate().compareTo( new DateTime().withMillisOfDay(0).toDate() )
        ).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(collect)) {

            if ( null != form.getId() ){
                if ( CollectionUtils.isNotEmpty(collect.stream().filter( o -> o.getId() == form.getId() ).collect(Collectors.toList())) ) {
                    return ;
                }
            }

            if ( 1 < collect.size()) {
                LOGGER.error("DFuelPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
                throw new BusinessException("油价变动已经存在未生效的记录");
            }

            DFuelPriceEffective effective = collect.get(0);
            if (null != form.getId() && form.getId() == effective.getId()) {
                return ;
            }
            if ( form.getEffectiveDate().compareTo(effective.getEffectiveDate()) == 1 ){
                return ;
            }

            LOGGER.error("DFuelPriceEffectiveServiceImpl.verificationBusiness already exist not active record");
            throw new BusinessException("油价变动已经存在未生效的记录");
        }
    }

    private void verificationForm(BindingResult br) {

        if (null == br) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            LOGGER.error("DRouteServiceImpl.add error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    @Override
    public void del(Integer id) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.delete param : {}", id);

        if ( null == id || 0 == id.intValue() ) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.del param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }


        DFuelPriceEffective effective = selectByPrimaryKey(id);
        if ( null == effective ){
            LOGGER.error("DFuelPriceEffectiveServiceImpl.del mile is null");
            throw new BusinessException("记录不存在");
        }

        Date today = new DateTime().withMillisOfDay(0).toDate();
        if ( 1 != effective.getEffectiveDate().compareTo(today)  ) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.del mile can not delete");
            throw new BusinessException("只能删除未生效的记录");
        }

        dFuelPriceEffectiveMapper.deleteByPrimaryKey(id);

        //更新当前记录失效时间为空
        DFuelPriceEffective currentEffective = this.selectByEffectiveDateAndFuelTypeId(effective.getFuelTypeId(), new Date());
        if ( null != currentEffective ) {
            currentEffective.setInvalidDate(null);
            dFuelPriceEffectiveMapper.updateByPrimaryKey(currentEffective);
        }
    }

    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, DFuelPriceEffectiveQueryConditions conditions) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);

//        if( null == pageVo ){
//            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectListByConditions param pageVo must not be null");
//            throw new IllegalArgumentException("分页信息不能为空");
//        }
        if (null == conditions) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectListByConditions param conditions must not be null");
            throw new IllegalArgumentException("查询条件信息不能为空");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " update_time DESC";
        }

        DFuelPriceEffectiveExample example = new DFuelPriceEffectiveExample();
        DFuelPriceEffectiveExample.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotBlank(conditions.getName())) {
            criteria.andNameLikeInsensitive("%" + conditions.getName() + "%");
        }

        if (null != conditions.getFuelTypeId()) {
            criteria.andFuelTypeIdEqualTo(conditions.getFuelTypeId());
        }

        if (null != conditions.getEffectiveDate()) {
            criteria.andEffectiveDateGreaterThanOrEqualTo(conditions.getEffectiveDate());
        }

        if (null != conditions.getInvalidDate()) {
            criteria.andInvalidDateLessThan(conditions.getInvalidDate());
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(dFuelPriceEffectiveExtMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }

        List<DFuelPriceEffectiveVo> list = dFuelPriceEffectiveExtMapper.selectByExample(example);

        //更新标示
        if ( CollectionUtils.isNotEmpty(list) ) {
            Date today = new DateTime().withMillisOfDay(0).toDate();
            list.stream().forEach( o -> {
                if ( 1 != o.getEffectiveDate().compareTo(today) ) {
                    o.setIsLock(true);
                }
            } );
        }

        map.put("list", list);

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }

    @Override
    public List<DFuelPriceEffective> selectNotEffective(Integer fuelTypeId) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.selectNotEffective param : {}", fuelTypeId);

        if (null == fuelTypeId) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectNotEffective param fuelTypeId must not be null");
            throw new IllegalArgumentException("燃油类型主键不能为空");
        }

        DFuelPriceEffectiveExample example = new DFuelPriceEffectiveExample();
        DFuelPriceEffectiveExample.Criteria criteria = example.createCriteria();
        criteria.andFuelTypeIdEqualTo(fuelTypeId);
        criteria.andInvalidDateIsNull();

        List<DFuelPriceEffective> list = dFuelPriceEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            DFuelPriceEffective effective = list.get(0);
            Date currentDate = new Date();
            if (null == effective.getInvalidDate() && currentDate.before(effective.getEffectiveDate())) {
                return list;
            }
//            else {
//                DFuelPriceEffectiveExample.Criteria criteria1 = example.createCriteria();
//                criteria1.andFuelTypeIdEqualTo(fuelTypeId).andEffectiveDateGreaterThan(new Date());
//                return dFuelPriceEffectiveMapper.selectByExample(example);
//            }
        }

        return null;
    }

    @Override
    public DFuelPriceEffective selectPreviousActive(Integer fuelTypeId, Date invalidDate) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.selectCurrentlyActive param : {}", fuelTypeId);

        if (null == fuelTypeId) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectCurrentlyActive param fuelTypeId must not be null");
            throw new IllegalArgumentException("燃油类型主键不能为空");
        }

        DFuelPriceEffectiveExample example = new DFuelPriceEffectiveExample();
        DFuelPriceEffectiveExample.Criteria criteria = example.createCriteria()
                .andEffectiveDateLessThanOrEqualTo(new Date());
        criteria.andFuelTypeIdEqualTo(fuelTypeId);
        if (null != invalidDate) {
            criteria.andInvalidDateLessThanOrEqualTo(invalidDate);
        } else {
            criteria.andInvalidDateIsNull();
        }

        List<DFuelPriceEffective> dFuelPriceEffectives = dFuelPriceEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(dFuelPriceEffectives)) {
            return dFuelPriceEffectives.get(0);
        }

        return null;
    }

    @Override
    public DFuelPriceEffective selectByPrimaryKey(Integer id) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.sellectByPrimaryKey param : {}", id);

        if (null == id) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.sellectByPrimaryKey param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        return dFuelPriceEffectiveMapper.selectByPrimaryKey(id);
    }

    @Override
    public void update(DFuelPriceEffective effective) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.update params : {}", effective);

        if (null == effective) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.update param effective must not be null");
            throw new IllegalArgumentException("燃油价格变动信息不能为空");
        }

        dFuelPriceEffectiveMapper.updateByPrimaryKeySelective(effective);
    }

    @Override
    public List<DFuelPriceEffective> selectByFuelTypeId(Integer fuelTypeId) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.selectByFuelTypeId param : {}", fuelTypeId);

        if (null == fuelTypeId) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectByFuelTypeId param fuelTypeId must not be null");
            throw new IllegalArgumentException("燃油类型主键不能为空");
        }

        DFuelPriceEffectiveExample example = new DFuelPriceEffectiveExample();
        example.createCriteria().andFuelTypeIdEqualTo(fuelTypeId);

        return dFuelPriceEffectiveMapper.selectByExample(example);
    }

    @Override
    public Integer update(DFuelPriceEffectiveForm form, BindingResult br) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.update param : {}", form);

        if (null == form) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("燃油价格变动表单不能为空");
        }

        //验证表单
        verificationForm(br);

        //验证业务
        verificationBusiness(form);

        /**
         * 新增燃油价格变动信息时更新上一条的失效时间为新增记录的生效时间
         */
        DFuelPriceEffective currentPrice = selectByEffectiveDateAndFuelTypeId(form.getFuelTypeId(), new Date());
        if (null != currentPrice) {
            currentPrice.setInvalidDate(form.getEffectiveDate());
            this.update(currentPrice);
        }

        /**
         * 更新车型每公里油费变动
         */
//        dVehiclePreKilometerFeeEffectiveService.updateByDFuelPriceEffective(effective.getId(), effective.getMarketPrice(), effective.getEffectiveDate());

        DFuelPriceEffective effective = new DFuelPriceEffective();
        BeanUtils.copyProperties(form, effective);

        return dFuelPriceEffectiveMapper.updateByPrimaryKeySelective(effective);
    }

    @Override
    public DFuelPriceEffective selectByEffectiveDateAndFuelTypeId(Integer fuelTypeId, Date effectiveDate) {
        LOGGER.info("DFuelPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId params : {}, {}", fuelTypeId, effectiveDate);

        if (null == fuelTypeId) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId param fuelTypeId must not be null");
            throw new IllegalArgumentException("燃油类型主键不能为空");
        }

        if (null == effectiveDate) {
            LOGGER.error("DFuelPriceEffectiveServiceImpl.selectByEffectiveDateAndFuelTypeId param effectiveDate must not be null");
            throw new IllegalArgumentException("生效时间不能为空");
        }

        DFuelPriceEffectiveExample example = new DFuelPriceEffectiveExample();
        example.createCriteria().andFuelTypeIdEqualTo(fuelTypeId)
                .andEffectiveDateLessThanOrEqualTo(effectiveDate)
                .andInvalidDateIsNull();

        List<DFuelPriceEffective> list = dFuelPriceEffectiveMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(list)) {

            DFuelPriceEffectiveExample example1 = new DFuelPriceEffectiveExample();
            example.createCriteria().andFuelTypeIdEqualTo(fuelTypeId)
                    .andEffectiveDateLessThanOrEqualTo(effectiveDate)
                    .andInvalidDateGreaterThan(new Date());

            list = dFuelPriceEffectiveMapper.selectByExample(example1);
        }

        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }

        return null;
    }
}
